﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KiDS_Bootstrap
{
	/// <summary>
	/// Spisak komandi koje sistem podrzava
	/// </summary>
	public enum CMD
	{
		CMD_REPLY_OK = 000,
		CMD_REPLY_FAIL = 001,
		CMD_UNKNOWN = 100,
		CMD_BOOTSTRAP_REGISTER_SERVENT = 101,
		CMD_BOOTSTRAP_UNREGISTER_SERVENT = 102,
		CMD_REGISTER_SERVENT = 103,
		CMD_UNREGISTER_SERVENT = 104,
		CMD_PING = 105,
		CMD_PONG = 106,
		CMD_SERVENT_MASTER_LIST = 107,
		CMD_REPLY_SERVENT_EXISTS = 108,
		ERROR_INVALID_PARAMS = 500,
		ERROR_GEOLEVEL_COUNT = 501,
		ERROR_GEOLEVEL_EXISTS = 502,
		ERROR_GEOLEVEL_NOT_FOUND = 503,
		CMD_POKE = 900

	}

	/// <summary>
	/// Extension klasa za CMD enumeraciju
	/// </summary>
	public static class Extensions
	{
		public static CMD cmd = CMD.CMD_REPLY_FAIL;
		/// <summary>
		/// Parsira komandu u stringovnu vrednost i postarava se da nijedan kod komande nema manje od tri cifre
		/// </summary>
		/// <param name="cmd">Komanda na kojom se metod poziva</param>
		/// <returns>Trocifren string komande</returns>
		public static string ParseInt(this CMD cmd)
		{
			if ((int)cmd >= 100)
				return (int)cmd + "";
			string temp = (int)cmd + "";
			if (temp.Length == 1)
				return "00" + temp;
			else return "0" + temp;
		}
	}

	/// <summary>
	/// 
	/// </summary>
	public class CommandFactory
	{
		public static Command MakeCommand(SOCKET socket, string socketAddress, string command, Bootstrap bootstrap)
		{
			Console.WriteLine(command);
			if(command == null || command == ""){
				return new ErrorCommand(socket, CMD.CMD_REPLY_FAIL.ParseInt(), CMD.ERROR_INVALID_PARAMS.ParseInt());
			}
			string[] parts = command.Split(' ');
			
			int cmdCode = -1;
			if (!Int32.TryParse(parts[0], out cmdCode))
			{
				return new ErrorCommand(socket, CMD.CMD_REPLY_FAIL.ParseInt(), CMD.ERROR_INVALID_PARAMS.ParseInt());
			}

			string cmd = command.Remove(0, parts[0].Length).Trim();
			switch (cmdCode)
			{
				case (int) CMD.CMD_BOOTSTRAP_REGISTER_SERVENT:
					if(parts.Length > 1)
						return new BootstrapRegisterServentCommand(socket, socketAddress, cmd, bootstrap);
					break;
				case (int) CMD.CMD_BOOTSTRAP_UNREGISTER_SERVENT:
					if(parts.Length > 1)
						return new BootstrapUnregisterServentCommand(socket, cmd);
					break;
				case (int) CMD.CMD_REGISTER_SERVENT:
					if(parts.Length > 1)
						return new RegisterServentCommand(socket, cmd);
					break;
				case (int) CMD.CMD_UNREGISTER_SERVENT:
					if(parts.Length > 1)
						return new UnregisterServentCommand(socket, cmd);
					break;
				case (int) CMD.CMD_PING:
					if(parts.Length > 1)
						return new PingPongCommand(socket, (int)CMD.CMD_PING, cmd);
					break;				
				default:
					break;
			}

			return new ErrorCommand(socket, CMD.CMD_REPLY_FAIL.ParseInt(), CMD.ERROR_INVALID_PARAMS.ParseInt() + "");
		}
	}
}
